function Shape3D(scene){
	this.id = new Date().getTime();
	this.position = {x:0,y:0,z:0};
	this.computedPosition = null;
	this.scene = scene;
	
	this.points = null;
	this.vertices = new Array();
	this.vertexBuffer = null;
	
	this.colors = null;
	this.verticeColors = null;
	this.colorsBuffer = null;
	
	this.vertexBuffer = null;
	this.itemSize = 0;
	this.numItems = 0;
	
	this.animations = new Array();
	
	this.drawType = null;
	this.vertexBufferType = null;
	this.colorBufferType = null;
	
	this.reset = function(){
		this.animations = new Array();
		this.computedPosition = null;
	}
	
	this.addAnimation = function(animation){
		this.animations.push(animation);
		this.scene.animationContext.add(animation);				
	}
	
	this.createVertices = function(){
	}
		
	
	this.added = function(){
		if(!this.scene) throw "Not really added isn't it?";
		this.context = this.scene.context;
		this.drawType = this.context.TRIANGLES;
		this.vertexBufferType = this.context.ARRAY_BUFFER;
		this.colorBufferType = this.context.ARRAY_BUFFER;
		this.createVertices();
		this.initBuffers();
	}
	
	this.initBuffers = function(){
		// init vertex buffer
		this.vertexBuffer = this.context.createBuffer();
		this.context.bindBuffer(this.context.ARRAY_BUFFER, this.vertexBuffer);
		this.context.bufferData(this.context.ARRAY_BUFFER, new Float32Array(this.vertices), this.context.STATIC_DRAW);
		this.vertexBuffer.itemSize = this.vertexSize;
		this.vertexBuffer.numItems = this.vertices.length/this.vertexSize;
		
		// init color buffer
		if(this.verticeColors){
			this.colorsBuffer = this.context.createBuffer();
			this.context.bindBuffer(this.context.ARRAY_BUFFER, this.colorsBuffer);
			this.context.bufferData(this.context.ARRAY_BUFFER, new Float32Array(this.verticeColors), this.context.STATIC_DRAW);
			this.colorsBuffer.itemSize = this.colorSize;
			this.colorsBuffer.numItems = this.verticeColors.length/this.colorSize;
		}
	}
	
	this.draw = function(){
		this.scene.mvMatrix =  mat4.create();
		mat4.identity(this.scene.mvMatrix);
				
		// draw according to camera position				
		mat4.translate(this.scene.mvMatrix, [-this.scene.cameraPosition.x, -this.scene.cameraPosition.y, -this.scene.cameraPosition.z]);
		mat4.rotate(this.scene.mvMatrix, this.scene.cameraAngles.x * Math.PI / 180, [-1, 0, 0]);
		mat4.rotate(this.scene.mvMatrix, this.scene.cameraAngles.y * Math.PI / 180, [0, -1, 0]);
		mat4.rotate(this.scene.mvMatrix, this.scene.cameraAngles.z * Math.PI / 180, [0, 0, -1]);			
		
		// draw to the object's real position
		//console.log(JSON.stringify([this.position.x, this.position.y, this.position.z]));
		mat4.translate(this.scene.mvMatrix, [this.position.x, this.position.y, this.position.z]);
		
		
		var animations =  this.animations.sort(function(a, b){return a.order-b.order});
		for(var i=0;i<animations.length;i++){
			//debugger;
			animations[i].execute(this);
		}
		this.context.bindBuffer(this.context.ARRAY_BUFFER, this.vertexBuffer);
		this.context.vertexAttribPointer(this.scene.shaderProgram.vertexPositionAttribute, this.vertexBuffer.itemSize, this.context.FLOAT, false, 0, 0);
		
		if(this.verticeColors){
			this.context.bindBuffer(this.context.ARRAY_BUFFER, this.colorsBuffer);
			this.context.vertexAttribPointer(this.scene.shaderProgram.vertexColorAttribute, this.colorsBuffer.itemSize, this.context.FLOAT, false, 0, 0);
		}
		//debugger;
		this.scene.setMatrixUniforms();
		this.context.drawArrays(this.drawType, 0, this.vertexBuffer.numItems);
	}
}